/*========================================================================================================================================================================================================
SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SAL
*****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    ***
SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SALVE     SALVE    SAL
*****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    *****     *****    ***

 PROJEKT:  Wetterstation MFC Siegendorf SLAVE v1.0final
 ERSTELLER: Dieter Schneider,Ing.
 DATUM:    
           06.11.12 FinalVersion für Auslieferung - analog zu v007
           09.10.12 v007 Firmwareversion in void setup mittels Serial.println hinzugefügt
		   26.09.12 v007 Sicherheitsfix für Arduino 1 reset bei auftreten eines Fehlers(Schleifenabbruch aus der Sim9000 While Schleife ) soll 
			  zu einem Neustart von Arduino 1 über Arduino 2 führen, sodass das System als auch das GPRS Modul neu gestartet wird.
			  Weiters soll ein System 1 reset auf der SD Card protokolliert ( ohne Timestamp ) werden dass dieser durch den Arduino 2 ausgeführt worden ist.
			  Der Start von Arduino 2 soll ebenfalls auf der SD Card ohne Timestamp protokolliert werden.
           07.08.12 v006 (ident zu v0051 nur höhere Ver Nr vergeben) inkl Watchdog für Arduino 1
           03.08.12 v005  retour nur auf SD Card schreiben von Eventls analog v0011
           03.08.12 v004x  serLCD und I2C Messdatenempfang wurde aufgrund zahlreicher Probleme verworfen
           02.08.12 v0033 bugfixed vom bugfixed 
           02.08.12 v0032 bugfixed Merker in loop zurücksetzen 
           01.08.12 v0031 String Split Methode
           31.07.12 v003 String Messdatenempfang
           30.07.12 v002 mit Seriellen LCD für Messwertausgabe 
           26.07.12  v0011

 
 FUNKTIONSBESCHREIBUNG:
 **********************
 
 Wetterstation zur Ermittlung folgender Größen:
 ----------------------------------------------
 

   -) Protokollierung der Ereignisse in LogFiles auf SD Card 
   
 Bedienung der Wetterstation:
 ----------------------------

     
       -) Empfang von Event via I2C zur Protokollierung auf SD Card von Arduino 1
       -) Protokollierung von Ereignisse wie SMS Ausgang Error Codes immer mittels Timestep protokollieren
       -) Watchdogfunktion Arduino 2 überwacht Arduino 1
       
       

       

       
 
 PROGRAMMBESCHREIBEUNG:
 **********************


 

 
 
 
 

 
 
 
 Arduino Anschlussbelegung
 *************************
 
 A0  
 A1  
 A2  
 A3  
 A4   I2C SDA
 A5   I2C SCL 
 D0  
 D1  
 D2  Run Led
 D3  Event LED empfangen und SD Card geschrieben
 D4  ON Status Ausgang für Watchdog auf Arduino 1
 D5  Reset Arduino 1
 D6  Eingang RUN Led Arduino 1
 D7  Eingang ON Arduino 1
 D8  Eingang für Resetaufforderung von System 1 durch SIM 9000 Fehler
 D9  
 D10 CS  SD
 D11 DatIn SD
 D12 DatOut SD 
 D13 CLk SD 
 
=========================================================================================================================================================================================================*/

  #include <Wire.h>
  #include <SD.h>
  #define ONPin  7																	  // Pin Nr für Eingang Arduino 1 ist an
  #define RUNPin 6																      // Pin Nr für Eingang Arduino 2 RUN Led
  #define Reset  5																  // Pin Nr für Ausgang Reset Arduino 2 ( Reset bei LOW - must be normal HIGH )
  #define SIM9000 8															          // Pin Nr für Eingang Reset Arduino 1 durch Sim9000 Fehler
  
  //Globale Var für Function loop()
  const signed long Polling      =  100000;//125000;                                     // Wert für Polling in µS Sensorwerte
  unsigned long g_StartTime = 0;                                                         // Startwert für Microsekungen zur LooprateMessung                                                   
  unsigned long g_EndTime   = 0;                                                         // Endwert für Microsekungen zur LooprateMessung    
  unsigned long g_CounterRate=0;
  unsigned long g_LoopRate = 0
  boolean g_running=false;                                                               // toggle Merker welcher im Sekundentakt ein aus geschaltet wird und die Abarbeitung des Programmes symbolisiert.
  
  //Globale Var für Function I2C recieve Event()
  byte g_counter=0;
  const int chipSelect = 10;
  
  //Globale Var für Watchdog
  byte g_state=1;																			//Zustand für Watchdog Statemachine
  byte g_kill =0;																			//Zähler für Reset Arduino 2
  byte g_WatchCount=0;
  boolean g_runToggle = false;
  byte g_runningCount=0;	

  void setup()
  { 
    pinMode(2,OUTPUT);
    pinMode(3,OUTPUT);
    Wire.begin(4);                // join i2c bus with address #4
    Wire.onReceive(receiveEvent); // register event
    Serial.begin(19200);           // start serial for output
	Serial.println("Firmwareversion MFC_Siegendorf_SLAVE_v1.ino Version v1.0final "); // Firmwareversion
    if (!SD.begin(chipSelect)) 
    {
      Serial.println("Card failed, or not present");
      // don't do anything more:
      return;
    }
    Serial.println("card initialized.");
    File dataFile = SD.open("logFile.txt", FILE_WRITE);
    if (dataFile)   // schreibe den Startlog auf die SD Card dass Arduino 2 gestartet worden ist. 
    {
      dataFile.println("Starte System 2 - SD Karte wurde initialisiert");
      dataFile.close();
    }
    pinMode(4,OUTPUT);
    digitalWrite(4,HIGH); // Arduino 2 ist ON für Watchdog auf Arduino 1
    pinMode(ONPin, INPUT);
    pinMode(RUNPin, INPUT);
    pinMode(SIM9000,INPUT);
    pinMode(Reset, OUTPUT);
    digitalWrite(Reset,LOW);																//auf LOW damit Arduino 2 nicht resetet wird => reset bei HIGH
	
  }
  
  void loop()
  {
    g_StartTime = micros();
    g_CounterRate++;                                                                      //für Polldauer zur Sensorabfrage
    g_EndTime = micros();
	
	if (digitalRead(RUNPin))
	{
		if (!g_runToggle)
		{
		 g_runningCount++;
		}
		g_runToggle = true;
	}
	
	if (!digitalRead(RUNPin))
	{
		if (g_runToggle)
		{
		 g_runningCount++;
		}
		g_runToggle = false;
	}

	if (g_CounterRate > 0 ) g_LoopRate =Polling/(g_EndTime - g_StartTime);
    if (g_CounterRate > g_LoopRate)                                                      // Erfassen der phys. Messwerte ==> Polling ca 1sec
    {
	   // Serial.print("g running Count");
	   // Serial.println(g_runningCount);
	   g_WatchCount++;
	   if (g_state<=2)
	   {
		Watchdog();
	   }
	   if ((g_WatchCount >= 30) && (g_state >= 3))										// nach 10 Durchläufen und wenn Ard2 ist running
	   {
		Watchdog();																		 // alle 10 Durchläufe ca 10sec Watchdog aufrufen
		g_WatchCount = 0;
	   }
	   else if (g_state <= 2)
	   {
		g_WatchCount = 0;
	   }
       g_CounterRate = 0;
       g_running = !g_running;                                                           // toggle von 0 auf 1 und 0 ==> wenn kann sekündliches toggeln feststellbar ist, dann ist der µC abgestürzt.
       if (g_running) digitalWrite(2,HIGH);
       else           digitalWrite(2,LOW);
    }
											    //Sicherheitsfix Reset von Arduino 1 aufgrund SIM9000 Fehler
    if(digitalRead(SIM9000)&&digitalRead(ONPin))					    // bei Resetaufforderung und Arduino 1 ist ON
    {
      File dataFile = SD.open("logFile.txt", FILE_WRITE);
      if (dataFile)   // Schreibe ins Logfile dass Arduino 1 soeben neu gestartet worden ist durch SIM 9000 Fehler
      {
        dataFile.println("Reset von Arduino 1 über Arduino 2 durchgeführt wegen SIM9000 Fehler");
	dataFile.close();
      }
      digitalWrite(Reset,HIGH); //  High Impuls steuert Transistor an welcher auf Masse durchschaltet
      delay(10);
      digitalWrite(Reset,LOW);
    }
  }
  
  // function that executes whenever data is received from master
  // this function is registered as an event, see setup()
  void receiveEvent(int howMany)
  {
   String Buffer ="";
   boolean incChar=false;    //wird true wenn Zeichen geschickt werden d.h wenn Buffer größer als 1byte ist ==> mindst 2 Zeichen
   
   while(1<Wire.available()) // loop through all but the last
    {
      incChar=true;
      char c = Wire.read(); // receive byte as a character
      Buffer += c;
    }
      File dataFile = SD.open("logFile.txt", FILE_WRITE);
      if (dataFile&&incChar)   // if the file is available und String wurde geschickt 
      {
        digitalWrite(3,HIGH);
        g_counter++;
        if (g_counter==1)
        {
          dataFile.print(Buffer);
          dataFile.close();
          //Serial.print(Buffer);
        }
        if (g_counter==2)
        {
          dataFile.println(Buffer);
          dataFile.close();
          g_counter=0;
          digitalWrite(3,LOW);
          //Serial.println(Buffer);
        }
      }
	Serial.println(Buffer);
    int x = Wire.read();    // muss vorhanden sein ansonsten hängt Programm
    //Serial.print("ausgabe von x integer :");Serial.println(x);
  }

  
//-------------------------------------------------------------Funktion für Watchdog Arduino 2---------------------------------------------------------------------------
void Watchdog()
{
	switch (g_state)
	{
		case 1://Zustand Arduino 2 ist AUS
			if (digitalRead(ONPin)==HIGH)
			{
				g_state=2;
				// Serial.print("State");Serial.println(g_state);
			}
			break;
		
		case 2://Arduino 2 ist eingeschaltet
			
			if (digitalRead(ONPin)==HIGH)
			{
				g_state=3;
				// Serial.print("State");Serial.println(g_state);
			}
			break;
		
		case 3: //Arduino 2 ist running
			if (g_runningCount >= 2)
			{
				g_runningCount = 0;
			}
			else 
			{
				g_kill++;
				// Serial.print("gkill ");
				// Serial.println(g_kill);
			}
			if (g_kill >=2 )
			{
				g_kill = 0;
				g_state = 4;
				// Serial.println("Reset");
			}
			break;
		
		case 4: // Reset wird durchgeführt;
                        {
                        File dataFile = SD.open("logFile.txt", FILE_WRITE);
      			if (dataFile)   // Schreibe ins Logfile dass Arduino 1 soeben neu gestartet worden ist
      			{
      			  dataFile.println("Reset von Arduino 1 über Arduino 2 durchgeführt!");
      			  dataFile.close();
      			}
			digitalWrite(Reset,HIGH); //  High Impuls steuert Transistor an welcher auf Masse durchschaltet
			delay(10);
			digitalWrite(Reset,LOW);
			g_state=1;
			g_runningCount = 0;
			break;
                        }
		
		default: //
			break;
	}

}
